#ifndef FILE_vector_t_H
#define FILE_vector_t_H

struct vector_t{
	int x, y;
	vector_t(){
		x = 0; y = 0;
	}
	vector_t(int px, int py){
		x = px; y = py;
	}
	vector_t(const vector_t& p){
		x = p.x; y = p.y;
	}
	vector_t inverted() const{
		return vector_t(-x,-y);
	}
	bool operator==(const vector_t& p) const {
		return p.x==x && p.y==y;
	}
	bool operator!=(const vector_t& p) const {
		return p.x!=x || p.y!=y;
	}
	vector_t operator+(const vector_t& v) const {
		return vector_t(v.x+x,v.y+x);
	}
	vector_t operator*(int scale) const {
		return vector_t(x*scale,y*scale);
	}
	bool isDiagonalOrStraightLine(){
		return x==0 || y==0 || x==y || x==-y;
	}
	/**
	 * \return a vector with x and y into [-1,0,1], that scaled with a
	 * certain positive number will give the original vector.
	 * If it cannot (isDiagonalOrStraightLine returned false), returns
	 * the closest matching diagonal (but not straight line). Do not rely
	 * on this error behaviour.
	 */
	vector_t normalized(){
		if(x==0){
			if(y==0)    { return vector_t( 0, 0); }
			else if(y<0){ return vector_t( 0,-1); }
			else        { return vector_t( 0, 1); }
		}
		if(y==0){
			if(x<0)     { return vector_t(-1, 0); }
			else        { return vector_t( 1, 0); }
		}
		if(x<0&&y<0)    { return vector_t(-1,-1); }
		if(x<0&&y>0)    { return vector_t(-1, 1); }
		if(x>0&&y<0)    { return vector_t( 1,-1); }
		if(x>0&&y>0)    { return vector_t( 1, 1); }
		return vector_t(0,0); // Failed.
	}
	/**
	 * With i in [0,8[, returns a different normalized vector for each i.
	 *
	 * The rotation starts at {1,0}, then {1,1}, ...
	 * If i is not in the given range, a modulo 8 is used.
	 */
	static vector_t iterateDirections(int i){
		switch(i%8){// No break, because of the returns.
			case 0: return vector_t( 1, 0);
			case 1: return vector_t( 1, 1);
			case 2: return vector_t( 0, 1);
			case 3: return vector_t(-1, 1);
			case 4: return vector_t(-1, 0);
			case 5: return vector_t(-1,-1);
			case 6: return vector_t( 0,-1);
			case 7: return vector_t( 1,-1);
			default: return vector_t();// Impossible.
		}
	}
	/**
	 * Tests the vector_t struct.
	 */
	static int _runTests(){
		if(vector_t(1,10).isDiagonalOrStraightLine()) return 1;
		if(!vector_t(-2,2).isDiagonalOrStraightLine()) return 1;
		if(vector_t(-2,2).normalized()!=vector_t(-1,1)) return 2;
		if(vector_t(0,30).normalized()!=vector_t(0,1)) return 2;
		if(vector_t(0,0).normalized()!=vector_t(0,0)) return 2;
		
		return 0;
	}
};

#endif // FILE_vector_t_H